#ifndef AVALON_BASICOSTREAMWRITER_HPP
#define AVALON_BASICOSTREAMWRITER_HPP
#include <ostream>
#include "Avalon/Base/Handle.hpp"
#include "Avalon/IO/Buffer.hpp"
#include "Avalon/IO/Writer.hpp"

namespace Avalon {
namespace IO {

  /*! \class BasicOStreamWriter
   *  \brief Wraps an std::basic_ostream for use with the Writer interface.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  template<typename _Elem = char, typename _Traits = std::char_traits<_Elem>>
  class BasicOStreamWriter : public Writer {
    public:

      //! Creates a BasicOStreamWriter.
      /*!
        \param destination The basic_ostream to wrap.
      */
      BasicOStreamWriter(Carry<std::basic_ostream<_Elem, _Traits>> destination)
          : m_destination(destination) {}

      virtual ~BasicOStreamWriter() {}

      virtual Threading::Async<void>::Ptr Write(const void* data, int size) {
        m_destination->write(static_cast<const _Elem*>(data),
          size / sizeof(_Elem));
        m_destination->flush();
        return Threading::NewAsync();
      }

      virtual Threading::Async<void>::Ptr Write(const Buffer& data) {
        return Write(data.GetData(), data.GetSize());
      }

    private:
      Handle<std::basic_ostream<_Elem, _Traits>> m_destination;
  };
}
}

#endif // AVALON_BASICOSTREAMWRITER_HPP
